<?php

if(!defined('OT_ROOT')) {
	exit('Access Denied');
}


class SaveImg{
	const IMG_EXT = 'jpg|jpeg|gif|bmp|png|webp';	// 远程图片保存类型
	public $oldImgStr;		// 源图片名集
	public $imgStr;			// 现图片名集
	public $errStr;			// 错误图片集
	public $errHtml;		// 错误字符集
	public $sizeStr;		// 图片大小集
	public $collErrStr;		// 采集错误

	public $judProxy = false;		// 是否使用代理
	public $saveOss = 'web';		// 图片存放点


	function __construct(){
		$this->oldImgStr	= '';
		$this->imgStr		= '';
		$this->errStr		= '';
		$this->errHtml		= '';
		$this->sizeStr		= '';
		$this->collErrStr	= '';
	}


	// 废弃，后期删除
	function ReplaceContent($contStr, $savePath, $maxSize=0, $currWebUrl='', $outPath=''){
		return $this->SaveContentImg($contStr, $savePath, $maxSize, $currWebUrl, $outPath);
	}
	// 替换字符串中的远程文件为本地文件并保存远程文件
	// $contStr 要处理的字符串； $savePath 保存文件的绝对路径； $maxSize 采集的图片最大大小； $currWebUrl 当前文件所在网页地址； $outPath 输出的图片路径（一般填相对路径，有时输出路径跟保存路径不同）
	function SaveContentImg($contStr, $savePath, $maxSize=0, $currWebUrl='', $outPath=''){
		global $appSysArr;
		$this->oldImgStr= '';
		$this->imgStr	= '';
		$this->errStr	= '';
		$this->errHtml	= '';
		$this->sizeStr	= '';
		$this->collErrStr	= '';

		if (substr($savePath,-1) != '/'){ $savePath .= '/'; }
		if (strlen($outPath) > 3){
			if (substr($outPath,-1) != '/'){ $outPath .= '/'; }
		}

		preg_match_all("/src\s*=\s*[\\\"|\']?((\s*[^>\\\"\'\s]*\.)(". self::IMG_EXT ."))/is",$contStr,$imgArr);
	//	preg_match_all("/(src|src)=[\"|'| ]{0,}((.*).(jpg|jpeg|gif|bmp|png))/is",$contStr,$imgArr);
		preg_match_all("/<img.*?src=[\'|\"](.*?)[\'|\"].*?[\/]?>/",$contStr,$imgArr2);
		$imgArr = array_unique( array_merge($imgArr[1],$imgArr2[1]) );	// 合并&去掉重复图片
		// print_r($imgArr);die();
		$imgOldArr = $imgArr;

		// 转换相对图片地址开始和已存在该网站上的图片
		if ($currWebUrl==''){
			$currWebUrl = dirname(GetUrl::HttpHead() . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
		}
		$nowWebUrl = strtolower(GetUrl::HttpHead() . $_SERVER['HTTP_HOST']);

		$ossUrlArr = AreaApp::OssUrlArr();
		foreach ($imgArr as $key => $val) {
			$val = trim($val);
			$imgType = AreaApp::OssUrlType($val, $ossUrlArr);
			if (stripos($val, $nowWebUrl) !== false || strlen($imgType) > 0){
				unset($imgArr[$key]);
			}else{
				$imgArr[$key] = $this->HttpUrl($val, $currWebUrl);
			}
		}

		// 如果没有图片则退出函数
		if (empty($imgArr)){
			return $contStr;
		}

		$isSaveFile = true;

		$sysImagesArr = Cache::PhpFile('sysImages');
		$saveDirPath = Info::DateTimeDir($sysImagesArr['SI_isDir']);
		if (strlen($saveDirPath) > 0){
			/* if (! File::CreateDir($upPath . $saveDirPath)){
				$saveDirPath = '';
			} */
		}

		// 判断并创建本地目录，分年和月保存
		$childDir = 'coll/'. $saveDirPath;
		$absDir = Str::RelToAbs($savePath . $childDir);
		if (! File::CreateMoreDir($absDir)){
			$childDir = 'coll/';
			$pathDir = $savePath . $childDir;
			if (! file_exists($pathDir)){
				$childDir = '';
			}
			$isSaveFile = false;
		}
		$savePath .= $childDir;
		if (strlen($outPath) > 3){
			$outPath .= $childDir;
		}

		// mime 和 扩展名 的映射
		$mimeArr = array(
			'image/bmp'	=> 'bmp',
			'image/gif'	=> 'gif',
			'image/jpeg'=> 'jpg',
			'image/png'	=> 'png',
			'image/ico'	=> 'ico',
			'image/webp'=> 'webp',
			);

		/*
		// 遍历图片信息测试
		// $imgArr[] = '';
		foreach ($imgArr as $key => $val){
			$headers = get_headers($val, 1);
			echo('<div>'. $val .' | '. print_r($headers,true) .'</div>');
		}
		die($currWebUrl);
		*/

		// 图片替换/保存
		foreach ($imgArr as $key => $val){
			$remFileUrl		= $val;
			$remFileUrlOld	= $imgOldArr[$key];
			if ($remFileUrl!='' && $isSaveFile==true){
				$newFileExt = strtolower(File::GetExt($remFileUrl));
				if (! in_array($newFileExt, explode('|', self::IMG_EXT))){
					$newFileExt = '';
					// 获取响应头
					if(( $headers = get_headers($remFileUrl, 1) ) !== false){
						// 获取响应的类型
						$type = $headers['Content-Type'];
						// 如果符合我们要的类型
						if(isset($mimeArr[$type])){
							$newFileExt = $mimeArr[$type];
						 }
					}
					if (strlen($newFileExt) == 0){
						continue;
					}
				}
				
				// 判断保存文件不能为以下文件类型
				if (strpos('|asp|asa|aspx|php|cer|cdx|exe|rar|zip|bat|','|'. $newFileExt .'|') !== false){
					continue;
				}
				
				$newFileName = 'OT'. File::GetNewName($newFileExt);
				$newFilePath = $savePath . $newFileName;
				
				// 执行保存操
				$srfArr = $this->SaveRemoteFile($newFilePath, $remFileUrl, $childDir . $newFileName, $maxSize, 1);
				if ($srfArr['res']){
					if (strlen($outPath) > 3){ $newFilePath = $outPath . $newFileName; }
					if (strlen($srfArr['url']) > 3){
						$srfImg = $srfArr['url'];
						$newFilePath = $srfArr['url'];
					}else{
						$srfImg = $childDir . $newFileName;
					}

					$this->oldImgStr	.= '|'. $remFileUrl;
					$this->imgStr		.= '|'. $srfImg;
					$this->sizeStr		.= '|'. $srfArr['size'];
					$contStr = str_replace($remFileUrlOld,$newFilePath,$contStr);
					
				}else{
					$this->errStr	.= '|'. $remFileUrl;
					$this->errHtml	.= '<div>'. $remFileUrl .' 保存到本地失败（'. $srfArr['note'] .'）</div>';
					$contStr = str_replace($remFileUrlOld,$remFileUrl,$contStr);
				}
			}elseif ($remFileUrl!='False' && $isSaveFile==false){	// 不保存图片
				$this->errStr	.= '|'. $remFileUrl;
				$this->errHtml	.= '<div>'. $remFileUrl .' 保存到本地失败（图片地址不对或路径目录创建失败）</div>';
				$contStr = str_replace($remFileUrlOld,$remFileUrl,$contStr);
			}
		}

		return $contStr;
	}


	// 获取内容图片集
	function GetImgUrlArr($contStr, $currWebUrl, $type='all'){
		preg_match_all("/src\s*=\s*[\\\"|\']?((\s*[^>\\\"\'\s]*\.)(". self::IMG_EXT ."))/is",$contStr,$imgArr);
	//	preg_match_all("/(src|src)=[\"|'| ]{0,}((.*).(jpg|jpeg|gif|bmp|png))/is",$contStr,$imgArr);
		if ($type == 'all'){
			preg_match_all("/<img.*?src=[\'|\"](.*?)[\'|\"].*?[\/]?>/",$contStr,$imgArr2);
			$imgArr = array_unique( array_merge($imgArr[1],$imgArr2[1]) );	// 合并&去掉重复图片
		}else{
			$imgArr = array_unique($imgArr[1]);
		}
	//	echo("【". $contStr ."|". $currWebUrl ."|/src\s*=\s*[\\\"|\']?((\s*[^>\\\"\'\s]*\.)(". self::IMG_EXT ."))/is】");
	//	print_r($imgArr);
		foreach ($imgArr as $key => $val) {
			$imgArr[$key] = $this->HttpUrl(trim($val), $currWebUrl);
		}
		return $imgArr;
	}


	// 获取内容图片集（没用到）
	function GetImgSrcArr($contStr, $type='all'){
		preg_match_all("/src\s*=\s*[\\\"|\']?((\s*[^>\\\"\'\s]*\.)(". self::IMG_EXT ."))/is",$contStr,$imgArr);
	//	preg_match_all("/(src|src)=[\"|'| ]{0,}((.*).(jpg|jpeg|gif|bmp|png))/is",$contStr,$imgArr);
		if ($type == 'all'){
			preg_match_all("/<img.*?src=[\'|\"](.*?)[\'|\"].*?[\/]?>/",$contStr,$imgArr2);
			$imgArr = array_unique( array_merge($imgArr[1],$imgArr2[1]) );	// 合并&去掉重复图片
		}else{
			$imgArr = array_unique($imgArr[1]);
		}
		return $imgArr;
	}


	// 废弃，后期删除
	function ReplaceRealUrlContent($contStr, $currWebUrl, $type='all'){
		return $this->ToContentImgUrl($contStr, $currWebUrl, $type);
	}
	// 内容里图片相对路径改为http路径
	// siContent：要处理的字符串；currWebUrl：当前网页地址
	function ToContentImgUrl($contStr, $currWebUrl, $type='all'){
		preg_match_all("/src\s*=\s*[\\\"|\']?((\s*[^>\\\"\'\s]*\.)(". self::IMG_EXT ."))/is",$contStr,$imgArr);
	//	preg_match_all("/(src|src)=[\"|'| ]{0,}((.*).(jpg|jpeg|gif|bmp|png))/is",$contStr,$imgArr);
		if ($type == 'all'){
			preg_match_all("/<img.*?src=[\'|\"](.*?)[\'|\"].*?[\/]?>/",$contStr,$imgArr2);
			$imgArr = array_unique( array_merge($imgArr[1],$imgArr2[1]) );	// 合并&去掉重复图片
		}else{
			$imgArr = array_unique($imgArr[1]);
		}
		
		if (! function_exists('newfuncImg')){
			function newfuncImg($a,$b){
				return strlen($a) < strlen($b) ? 1 : -1;
			}
		}
		usort($imgArr, 'newfuncImg');

		$imgArr = array();
		$imgNum = 0;
		foreach ($imgArr as $val) {
			$imgArr[$imgNum] = $this->HttpUrl(trim($val), $currWebUrl);
			$contStr = str_replace($val, '[OTarr'. $imgNum .']', $contStr);
			$imgNum ++;
		}
		$imgNum = 0;
		foreach ($imgArr as $val) {
			$contStr = str_replace('[OTarr'. $imgNum .']', $val, $contStr);
			$imgNum ++;
		}
		return $contStr;
	}


	// 保存远程的文件到本地
	// siLocalFile:本地文件名（绝对路径/相对路径）；siRemoteFile:远程文件URL；siOssFile:云存储文件名；siImgMaxSize:下载文件最大大小(KB)
	function SaveRemoteFile($siLocalFile, $siRemoteFile, $siOssFile='', $maxSize=10240, $siWater=1){
		global $sysImagesArr;
		$retArr = array('res'=>false, 'size'=>0, 'oss'=>'web', 'url'=>'', 'note'=>'');
		$getFileStr = $this->GetUrlContent($siRemoteFile,60);
		/* if(empty($getFileStr)){
			@sleep(1);
			$getFileStr = $this->GetUrlContent($siRemoteFile,30);
		} */
		if(! empty($getFileStr) ){
			$retSize = strlen($getFileStr);
			$retArr['size'] = $retSize;
			if ($maxSize>0 && $retSize>$maxSize*1024){
				$this->collErrStr = '图片/文件大小超出设定的最大值('. $retSize .'|'. $maxSize*1024 .')';
				$retArr['note'] = $this->collErrStr;
				return $retArr;
			}elseif ($retSize == 5 && strtolower($getFileStr) == 'false'){
				$this->collErrStr='图片/文件内容为false';
				$retArr['note'] = $this->collErrStr;
				return $retArr;
			}
			$fp = fopen($siLocalFile,'w');
			$isWrite = fwrite($fp,$getFileStr);
			fclose($fp);
			if(! $isWrite){
				$this->collErrStr='无法保存到本地';
				$retArr['note'] = $this->collErrStr;
				return $retArr;
			}else{
				$retArr['res'] = true;
				if ($siWater == 1){
					if (empty($sysImagesArr)){ $sysImagesArr = Cache::PhpFile('sysImages'); }

					// 文字水印
					if ($sysImagesArr['SI_isWatermark'] == 'font'){
						$imgWaterArr=array();
						$imgWaterArr['upLoadImg']	= $siLocalFile;
						$imgWaterArr['waterPos']	= $sysImagesArr['SI_watermarkPos'];
						$imgWaterArr['waterPadding']= $sysImagesArr['SI_watermarkPadding'];
						$imgWaterArr['waterText']	= $sysImagesArr['SI_watermarkFontContent'];
						$imgWaterArr['textFont']	= $sysImagesArr['SI_watermarkFontSize'];
						$imgWaterArr['textColor']	= $sysImagesArr['SI_watermarkFontColor'];
						Images::Watermark($imgWaterArr);

					// 图片水印
					}elseif ($sysImagesArr['SI_isWatermark'] == 'img'){
						$waterPath = OT_ROOT . ImagesFileDir . $sysImagesArr['SI_watermarkPath'];
						$imgWaterArr=array();
						$imgWaterArr['upLoadImg']	= $siLocalFile;
						$imgWaterArr['waterPos']	= $sysImagesArr['SI_watermarkPos'];
						$imgWaterArr['waterPadding']= $sysImagesArr['SI_watermarkPadding'];
						$imgWaterArr['waterTrans']	= $sysImagesArr['SI_watermarkTrans'];
						$imgWaterArr['waterImg']	= $waterPath;
						Images::Watermark($imgWaterArr);

					}
				}
				if ( strlen($siOssFile) > 0 && in_array($this->saveOss, AreaApp::OssNameArr()) ){
					$retArr['oss'] = $this->saveOss;
					$ossArr = AreaApp::OssDeal($this->saveOss, $siOssFile, $siLocalFile);	// pathinfo($siLocalFile,PATHINFO_BASENAME)
					if ($ossArr['res']){
						$retArr['url'] = $ossArr['path'];
					}
				}
			}
			$retArr['note'] = '保存成功';
			// @sleep(2);
		}else{
			$this->collErrStr='获取不到图片/文件';
			$retArr['note'] = $this->collErrStr;
			return $retArr;
		}
		return $retArr;
	}


	// 废弃，后期删除
	function RealUrl($getStrUrl,$currUrl){
		return $this->HttpUrl($getStrUrl,$currUrl);
	}
	// 将相对地址转换为http绝对地址
	// getStrUrl:要转换的相对地址；currUrl:当前网页地址
	function HttpUrl($getStrUrl,$currUrl){
		$retStr = '';
		$Pi=0;
		$Ci=0;
		$getStrUrlArr=array();
		$currUrlArr=array();

		if ($getStrUrl=='' || $currUrl=='' || $getStrUrl=='False' || $currUrl=='False'){
			$retStr = $getStrUrl;
		}
		if (substr(strtolower($currUrl),0,7)!='http://' && substr(strtolower($currUrl),0,8)!='https://'){
			$currUrl= GetUrl::HttpHead() . $currUrl;
		}
		$currUrl	= str_replace(array("\\","://"),array("/",":\\\\"),$currUrl);
		$getStrUrl	= str_replace("\\","/",$getStrUrl);

		if (substr($currUrl,-1)!='/'){
			if (strpos($currUrl,'/') !== false){
				if (strpos(substr($currUrl,strrpos($currUrl,'/')+1),'.') !== false){
				}else{
					$currUrl .= '/';
				}
			}else{
				$currUrl .= '/';
			}
		}
		$currUrlArr=explode('/',$currUrl);

		if (substr($getStrUrl,0,2) == '//'){
			return 'http:'. $getStrUrl;

		}else if (substr(strtolower($getStrUrl),0,7) == 'http://' || substr(strtolower($getStrUrl),0,8) == 'https://'){
			$retStr = str_replace("://",":\\\\",$getStrUrl);

		}else if (substr($getStrUrl,0,1) == '/'){
			$retStr = $currUrlArr[0] . $getStrUrl;

		}else if (substr($getStrUrl,0,2) == './'){
			$getStrUrl=substr($getStrUrl,2);
			if (substr($currUrl,-1)=='/'){   
				$retStr = $currUrl . $getStrUrl;
			}else{
				$retStr = substr($currUrl,0,strrpos($currUrl,'/')+1) . $getStrUrl;
			}

		}else if (substr($getStrUrl,0,3)=='../'){
			while (substr($getStrUrl,0,3)=='../'){
				$getStrUrl=substr($getStrUrl,3);
				$Pi ++;
			}
			for ($Ci=0; $Ci<count($currUrlArr)-1-$Pi; $Ci++){
				if ($retStr!=''){
					$retStr .= '/'. $currUrlArr[$Ci];
				}else{
					$retStr = $currUrlArr[$Ci];
				}
			}
			if ($retStr==''){ $retStr = $currUrlArr[0]; }
			$retStr .= '/'. $getStrUrl;

		}else if (substr($getStrUrl,0,1)=='?'){
			if (strpos($currUrl,'?') !== false){   
				$retStr = substr($currUrl,0,strpos($currUrl,'?')) . $getStrUrl;
			}else{
				$retStr = $currUrl . $getStrUrl;
			}

		}else{
			if (strpos($getStrUrl,'/') !== false){
				$getStrUrlArr=explode('/',$getStrUrl);
				if (strpos($getStrUrlArr[0],'.') !== false){
					if (substr($getStrUrl,-1)=='/'){
						$retStr = 'http:\\'. $getStrUrl;
					}else{
						if (strpos($getStrUrlArr[count($getStrUrlArr)-2],'.') !== false){
							$retStr = 'http:\\'. $getStrUrl;
						}else{
							$retStr = 'http:\\'. $getStrUrl .'/';
						}
					}
				}else{
					if (substr($currUrl,-1)=='/'){ 
						$retStr = $currUrl . $getStrUrl;
					}else{
						$retStr = substr($currUrl,0,strrpos($currUrl,'/')+1) . $getStrUrl;
					}
				}
			}else{
				if (strpos($getStrUrl,'.') !== false){
					if (substr($currUrl,-1)=='/'){
						if (in_array(substr(strtolower($getStrUrl),-3),array('.cn','com','net','org'))){
							$retStr = 'http:\\'. $getStrUrl .'/';
						}else{
							$retStr = $currUrl . $getStrUrl;
						}
					}else{
						if (in_array(substr(strtolower($getStrUrl),-3),array('.cn','com','net','org'))){
							$retStr = 'http:\\'. $getStrUrl .'/';
						}else{
							$retStr = substr($currUrl,0,strrpos($currUrl,'/')+1) .'/'. $getStrUrl;
						}
					}
				}else{
					if (substr($currUrl,-1)=='/'){
						$retStr = $currUrl . $getStrUrl .'/';
					}else{
						$retStr = substr($currUrl,0,strrpos($currUrl,'/')+1) .'/'. $getStrUrl .'/';
					}         
				}
			}
		}

		if (substr($retStr,0,1)=='/'){
			$retStr = substr($retStr,1);
		}
		if ($retStr != ''){
			$retStr = str_replace('//','/',$retStr);
			$retStr = str_replace(":\\\\",'://',$retStr);
		}else{
			$retStr = $getStrUrl;
		}
		return $retStr;
	}


	// 获取需要的地址段
	// currUrl:待处理网址；rank:级数，0根地址，1子目录地址，2孙目录地址...
	function RankUrl($currUrl,$rank){
		$retStr = '';

		if ($currUrl==''){
			return $currUrl;
		}
		if (substr(strtolower($currUrl),0,7)!='http://' && substr(strtolower($currUrl),0,8)!='https://'){
			$currUrl= GetUrl::HttpHead() . $currUrl;
		}
		$currUrl	= str_replace(array("\\","://"),array("/",":\\\\"),$currUrl);

		if (substr($currUrl,-1)!='/'){
			if (strpos($currUrl,'/') !== false){
				if (strpos(substr($currUrl,strrpos($currUrl,'/')+1),'.') !== false){
				}else{
					$currUrl .= '/';
				}
			}else{
				$currUrl .= '/';
			}
		}
		$currUrlArr=explode('/',$currUrl);

		if ($rank>(count($currUrlArr)-2)){
			$rank = count($currUrlArr)-2;
		}
		for ($Ci=0; $Ci<=$rank; $Ci++){
			if ($retStr!=''){
				$retStr .= '/'. $currUrlArr[$Ci];
			}else{
				$retStr = $currUrlArr[$Ci];
			}
		}

		if ($retStr!=''){
			$retStr = str_replace(array("//",":\\\\"),array('/','://'),$retStr);
		}else{
			$retStr = $currUrl;
		}
		return $retStr;
	}


	// 建立目录
	function CreateDir($dir){
		$retJud=false;
		if (! is_dir($dir)){
			if (mkdir($dir, 0755)){
				$retJud=true;
			}
			//创建index.html,目的防止列目录漏洞
			//fclose(fopen($dir.'/index.html', 'w'));
			@chmod($dir, 0755);
		}else{
			$retJud=true;
		}
		return $retJud;
	}

	// 检查目录是否存在
	function CheckDir($dir){
		if (is_dir($dir)) { 
			return true;
		}else{ 
			return false;
		} 
	}


	function GetUrlContent($url, $timeout=30){
		global $DB,$systemArr;

		class_exists('ReqUrl',false) or require(OT_ROOT .'inc/classReqUrl.php');

		if ($this->judProxy && strlen($systemArr['SYS_proxyIpList']) > 8){
			$proxyIp = '';
			$proxyPort = 80;
			$currIp = Area::ListPoint('proxyIp',$systemArr['SYS_proxyIpList']);
			$oneArr = explode(':', $currIp);
			$proxyIp = $oneArr[0];
			if (count($oneArr) >= 2){ $proxyPort = $oneArr[1]; }

			$retArr = ReqUrl::ProxyCurl('GET', $url, array('ip'=>$proxyIp,'port'=>$proxyPort));
		}else{
			$retArr = ReqUrl::UseAuto(0, 'GET', $url);
		}
		if (! $retArr['res']){ $retStr='False'; }else{ $retStr=$retArr['note']; }
/*
		if ( function_exists('curl_init') ){
			$ch = curl_init();
			curl_setopt ($ch, curlopt_url, $url);
			curl_setopt ($ch, curlopt_returntransfer, 1);
			curl_setopt ($ch, curlopt_connecttimeout, $timeout);
			$retStr = curl_exec($ch);
			curl_close($ch);
		}elseif ( ini_get('allow_url_fopen') == 1 || strtolower(ini_get('allow_url_fopen')) == 'on' ){
			$retStr = @file_get_contents($url);
		}else {
			class_exists('Snoopy',false) or include(OT_ROOT .'inc/Snoopy.class.php');
			$snoopy = new Snoopy();
			$snoopy->fetch($url);
			$retStr = $snoopy->results;
		}
*/
		return $retStr;
	}

}
?>